﻿using MusicPlayerPlus.Interface.Base;
using MusicPlayerPlus.Interface.Model.Enum;
using MusicPlayerPlus.Interface.Model.Muisc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;

namespace MusicPlayerPlus.PlugIn.MediaCore
{
    public class PlugIn : InterfaceBase,
        //Input
        MusicPlayerPlus.Interface.Base.Action.Input.IChangeTimeLineAction,
        MusicPlayerPlus.Interface.Base.Action.Input.IChangeVolumeAction,
        MusicPlayerPlus.Interface.Base.Action.Input.IPlayAction,
        MusicPlayerPlus.Interface.Base.Action.Input.IPauseAction,
        MusicPlayerPlus.Interface.Base.Action.Input.IStopAction,
        MusicPlayerPlus.Interface.Base.Action.Input.ISetMainWindow,
        MusicPlayerPlus.Interface.Base.Action.Input.IAutoExecuteAction,
        MusicPlayerPlus.Interface.Base.Action.Input.IPlayMusicChange,
        //Output
        MusicPlayerPlus.Interface.Base.Action.Output.ITimeLineChangeAction,
        MusicPlayerPlus.Interface.Base.Action.Output.IBufferingTimeLineChangeAction,
        MusicPlayerPlus.Interface.Base.Action.Output.IVolumeChangeAction,
        MusicPlayerPlus.Interface.Base.Action.Output.IPlayStateChangeAction
    {
        #region Input

        /// <summary>
        /// (主动)进度条改变
        /// </summary>
        public void ChangeTimeLine(double val)
        {
            mediaElement.Position = TimeSpan.FromSeconds(val);
        }
        /// <summary>
        /// (主动)音量改变
        /// </summary>
        public void ChangeVolume(double val)
        {
            mediaElement.Volume = val;
            VolumeChange_Action(mediaElement.Volume);
        }
        /// <summary>
        /// 播放
        /// </summary>
        public void Play()
        {
            mediaElement.Play();
            PlayStateChange_Action(MediaPlayState.Play);
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void Pause()
        {
            mediaElement.Pause();
            PlayStateChange_Action(MediaPlayState.Pause);
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            mediaElement.Stop();
            PlayStateChange_Action(MediaPlayState.Stop);
        }
        /// <summary>
        /// 设置主窗体
        /// </summary>
        public void SetMainWindow(object win)
        {
            System.Windows.Window window = win as System.Windows.Window;
            if (window != null)
            {
                Grid mainGrid = window.Content as Grid;
                if (mainGrid != null)
                {
                    mainGrid.Children.Add(this.mediaElement);
                }
            }
        }
        public void PlayMusicChange(MusicItem item)
        {
            if (item != null)
            {
                string val = "";
                if (item.Type == MusicSourceType.Local)
                {
                    val = item.Location;
                }
                else
                {
                    val = item.Url;
                }
                mediaElement.Source = new Uri(val);
                mediaElement.Play();
                PlayStateChange_Action(MediaPlayState.Play);
            }
        }

        /// <summary>
        /// 自动执行动作接口
        /// </summary>
        public void AutoExecute()
        {
            mediaElement.LoadedBehavior = MediaState.Manual;
            mediaElement.Volume = 1;
            mediaElement.MediaEnded += mediaElement_MediaEnded;
            mediaElement.MediaFailed += mediaElement_MediaFailed;
            mediaElement.MediaOpened += mediaElement_MediaOpened;
            mediaElement.BufferingEnded += mediaElement_BufferingEnded;
            mediaElement.BufferingStarted += mediaElement_BufferingStarted;

            timer.Tick += timer_Tick;
            timer.Interval = new TimeSpan(0, 0, 0, 0, 500);
            timer.Start();
        }

        #endregion

        #region Output

        /// <summary>
        /// (改变后事件)进度条改变
        /// </summary>
        public Action<double, double> TimeLineChange_Action { private get; set; }
        /// <summary>
        /// (改变后事件)音量改变
        /// </summary>
        public Action<double> VolumeChange_Action { private get; set; }
        /// <summary>
        /// 缓冲进度条改变
        /// </summary>
        public Action<double, double> BufferingTimeLineChange_Action { private get; set; }
        /// <summary>
        /// 播放状态改变
        /// </summary>
        public Action<MediaPlayState> PlayStateChange_Action { private get; set; }

        #endregion

        #region Object

        MediaElement mediaElement = new MediaElement();
        System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();

        #endregion

        #region Event

        void timer_Tick(object sender, EventArgs e)
        {
            if (!mediaElement.HasAudio && !mediaElement.HasVideo && !mediaElement.NaturalDuration.HasTimeSpan)
            {
                return;
            }
            try
            {
                TimeSpan max = mediaElement.NaturalDuration.TimeSpan;
                TimeSpan val = mediaElement.Position;

                TimeLineChange_Action(max.TotalSeconds, val.TotalSeconds);
                BufferingTimeLineChange_Action(1, mediaElement.BufferingProgress);
            }
            catch (Exception)
            {
                return;
            }
        }

        void mediaElement_BufferingStarted(object sender, System.Windows.RoutedEventArgs e)
        {

        }

        void mediaElement_BufferingEnded(object sender, System.Windows.RoutedEventArgs e)
        {

        }

        void mediaElement_MediaOpened(object sender, System.Windows.RoutedEventArgs e)
        {
            //timer.Start();
            PlayStateChange_Action(MediaPlayState.Play);
        }

        void mediaElement_MediaFailed(object sender, System.Windows.ExceptionRoutedEventArgs e)
        {
            //timer.Stop();
            PlayStateChange_Action(MediaPlayState.Error);
        }

        void mediaElement_MediaEnded(object sender, System.Windows.RoutedEventArgs e)
        {
            //timer.Stop();
            PlayStateChange_Action(MediaPlayState.End);
        }

        #endregion

        #region Method


        #endregion
    }
}
